import SensorUtils from "../SensorUtils.js";
import component from "../../Component.js"
import Type, {LayerType, ServiceType, TreeNodeParent} from "../../../experience/db/Type.js"

const Draw = ol.interaction.Draw;
const Pointer = ol.interaction.Pointer;
const Modify = ol.interaction.Modify;
const Select = ol.interaction.Select;

const Stroke = ol.style.Stroke;
const Fill = ol.style.Fill;
const Icon = ol.style.Icon;
const Style = ol.style.Style;
const CircleStyle = ol.style.Circle;

// 最外层目录的那几个节点的名称
const rootNodeList = [
    '安全监控',
    '人员定位',
    '应急广播',
    '视频监控',
    '通风系统'
]

export default class SensorEdit extends component {
    constructor() { super() }

    async control() {
        this.ztreeUtil = new SensorUtils();
        this.DragCoordinate = null;
        this.PointerInteraction = null;
        // this.modifyInteraction = null
        // 当前触发gis点击的 通风传感器的 node_id 存储的值
        this.current_ventilate_featrue = null;
        // 断电区域按钮的小弹窗 当前的显示状态。
        this.PAreaSlideBoxIsShow = false;

        // 初始化 设备选择 断点区域按钮的行为
        this.$$("#equipSelect").on('click',function (event) {
            const dom = document.querySelector('#eqDialog');
            const height = dom.clientHeight;
            if(height > 0) {
                dom.style.height = 0;
            } else {
                dom.style.height = 'auto';
            }
        });

        $(document).ready(() => {
            this.tree_init(true);

            // 初始化完成之后 直接把 gis上的modify的交互打开，方便用户去进行位置修改
            this.selectInteraction = new Select();
            this.selectInteraction.on('select', async (event) => {
                const selectedArr = event.selected;
                const res = selectedArr.find((f) => f.get('service_type'));
                if (!res) {
                    // 表示选中的是底图上的巷道元素或者通风系统的风向线元素。
                    console.log('选中巷道元素', selectedArr);
                    if (selectedArr.length > 0) {
                        const underLayFeature = selectedArr[0];
                        const f_id = underLayFeature.get('id');
                        const type = underLayFeature.get('type');
                        console.log('f_id => ', f_id, 'type => ', type);
                        if (type === LayerType.SMVentilate) {
                            // 准备删除 风向线元素
                            this.emitter.emit('delete-ventilate', f_id);
                        } else if (type === LayerType.SMVentilateAnimation) {
                            // 说明用户点击到了 风向动画的元素。 让他什么也不干
                        } else {
                            const res = await this.db.operation(type, 'get', f_id);
                            res.type = type;
                            this.currentSelectUnderLayFeature = res;
                            this.layerChangeDialog.open();
                        }
                        this.selectInteraction.getFeatures().clear();
                    }
                } else {
                    // 到了这里说明select选中的是 gis上面的元素
                    // 1.再判断选中的元素是否是断电区域
                    if (res.get('service_type') === ServiceType.PoweredArea) {
                        // 1.移除选中
                        this.selectInteraction.getFeatures().clear();
                        // 2.判断 当前用户是否已经 激活断电区域选中(根据localstorage)
                        const SelectIsPowerArea = localStorage.getItem('PA_select_status');
                        if (SelectIsPowerArea === 'true') {
                            // 直接传出 多边形的feature
                            this.emitter.emit('send-powered-area', res);
                        }
                    }
                }
            });

            this.drawer.addInteraction(this.selectInteraction);
            const gasSource = this.drawer.source(LayerType.SMGas);
            const staffSource = this.drawer.source(LayerType.SMStaff);
            const broadcastSource = this.drawer.source(LayerType.SMBroadCast);
            const commonStyle = new Style({
                image: new Icon({
                    src: 'assets/images/safe_monitor/touming.svg',
                    scale: 0.1
                })
            });
            const gasModifyInteraction = new Modify({
                source:gasSource,
                style:commonStyle
            });
            const staffModifyInteraction = new Modify({
                source:staffSource,
                style:commonStyle
            });
            const broadcastModifyInteraction = new Modify({
                source:broadcastSource,
                style:commonStyle
            });
            const ModifyInteractionArr = [gasModifyInteraction, staffModifyInteraction, broadcastModifyInteraction];
            ModifyInteractionArr.forEach((modifyInteraction) => {
                modifyInteraction.on('modifyend', (event) => {
                    const features = event.features;
                    // 生成 promise 数组
                    const featuresArr = features.getArray();
                    const Pos = featuresArr.map((feature) => {
                        return new Promise((resolve) => {
                            const Coordinates = feature.getGeometry().getCoordinates();
                            const node_id = feature.get('node_id');
                            const service_type = feature.get('service_type');
                            const layer_type = feature.get('type');
                            this.api.updatePosition({
                                mine_id: ServiceType.Mine_Id,
                                node_id: node_id,
                                service_type: service_type,
                                x: this.algo.denormalX(Coordinates[0]),
                                y: this.algo.denormalY(Coordinates[1]),
                                layer: layer_type
                            }).then(() => {
                                resolve()
                            })
                        })
                    })

                    Promise.all(Pos).then(async () => {
                        await this.ztreeUtil.PositionDbRefresh();
                        this.selectInteraction.getFeatures().clear();
                    })
                })
            });

            ModifyInteractionArr.forEach((interaction) => this.drawer.addInteraction(interaction));

            // 为编辑模式下 添加 断电区域编辑按钮的点击事件
            $("#powerdownArea").on('click', (event) => {
                if (!this.PAreaSlideBoxIsShow) {
                    $("#PAreaSlideBox").animate({left: '70px', width: '60px'}, 'slow');
                    $("#AreaIconsContainer").animate({width: '25px'}, 'slow');
                    this.PAreaSlideBoxIsShow = !this.PAreaSlideBoxIsShow;
                } else {
                    $("#PAreaSlideBox").animate({left: '-10px', width: '0px'}, 'slow');
                    $("#AreaIconsContainer").animate({width: '0px'}, 'slow');
                    this.PAreaSlideBoxIsShow = !this.PAreaSlideBoxIsShow;
                }
            });
            // 创建 地图元素 图层切换的dialog
            this.layerChangeDialog = this.createrFeatureLayerChangeDialog();
        });
    }

    template() {
        const treeNodesDialog = `
            <div id="eqDialog" class="equipSelectDialog">
                <div class="cardTitle">
                    <h4 class="title_text">选择设备</h4>
                    <div class="truncateBox"></div>
                </div>
                <ul id="treeDemo" class="ztree" style="height: 280px;margin: 0;background-color: #fff"></ul>
            </div>
        `;
        // 编辑模式下，断电区域的button,先将断电区域的功能隐藏掉
        const poweredAreaButton = `
            <div id="powerdownArea"  class="GisUtilIcon" 
                style="display:none; position: absolute; top: 150px; left: 25px; z-index: 999;">
                <i class="fas fa-map"></i>
            </div>
        `;
        // 点击 断电区域button,右侧要滑出的小弹窗
        const PAreaSlideBox = `
            <div id="PAreaSlideBox"  class="P_slideBox" 
                style="position: absolute;top: 140px;left: -60px;z-index: 900;">
                <div id="AreaIconsContainer">
                    <i id="pAreaDraw" class="fas fa-pencil-alt" 
                        style="font-size:18px;color:rgb(51, 51, 51)">
                    </i>
                    <i id="pAreaPoint" class="fas fa-mouse-pointer" 
                        style="font-size:18px;color:rgb(51, 51, 51)">
                    </i>
                </div>
            </div>
        `;
        const equipSelect = `
            <div id="equipSelect" class="GisUtilIcon" 
                style="position: absolute; top: 100px; left: 25px; z-index: 999">
                <i class="fas fa-flag"></i>
            </div>
        `;
        this.$$("body").append(equipSelect);
        this.$$("body").append(treeNodesDialog);
        this.$$("body").append(poweredAreaButton);
        this.$$("body").append(PAreaSlideBox);
    }

    async treeNodeDataInit() {
        // 获取全部树节点
        const { data: staffs } = await this.ztreeUtil.getAllStaffNodes();
        const { data: broadcasts } = await this.ztreeUtil.getAllBroadCastNodes();
        const { data: videos } = await this.ztreeUtil.getAllVideoNodes();
        const { data: gass } = await this.ztreeUtil.getAllGasNodes();
        // 获取全部已被选择的树节点
        const { data: selectedStaffs } = await this.ztreeUtil.getSelectedStaffNodes();
        const { data: selectedBroadcast} = await this.ztreeUtil.getSelectedBroadCastNodes();
        const { data: selectedVideo } = await this.ztreeUtil.getSelectedVideoNodes();
        const { data: selectedGass } = await this.ztreeUtil.getSelectedGasNodes();

        // 获取通风设备
        const { data: ventination } = await this.ztreeUtil.getSmVentilation();
        // 获取全部 m_position 的位置信息
        const { data: m_position_data } = await this.api.getSmPositions(ServiceType.Mine_Id);
        ventination.forEach((el) => {
            el.parent_id = TreeNodeParent.Ventilate;
            el.name = `${el.id}-${el.placement}`;
            el.node_id = el.id;
            el.isselected = false;
            delete el.id;
            if (m_position_data.some((item) => item.node_id === el.node_id)) {
                el.isselected = true;
            }
        });

        // ventination 表示全部格式化过的通风设备,用isselected属性表示 该通风设备是否被设置过位置
        staffs.forEach((node) => {
            node.isselected = selectedStaffs.some((selectNode) => {
                return node.node_id === selectNode.node_id;
            });
        });

        videos.forEach((node) => {
            node.isselected = selectedVideo.some((selectNode) => {
                return node.node_id === selectNode.node_id;
            })
        });

        broadcasts.forEach((node) => {
            node.isselected = selectedBroadcast.some((selectNode) => {
                return node.node_id === selectNode.node_id;
            })
        });

        const ExtractGass = this.ztreeUtil.gasNodesInfoExtract(gass);

        // 第一次遍历 将所有节点的 isselected属性 设置上
        ExtractGass.forEach((gas) => {
            const res = selectedGass.find(el => el.node_id === gas.node_id);
            if (gas.parent_id === ServiceType.Gas) {
                // gas.open = false
                // gas.isParent = true
                // gas.iconClose = '../../assets/images/safe_monitor/tree/diractory_close.png'
                // gas.iconOpen = '../../assets/images/safe_monitor/tree/diractory_open.png'
            }
            gas.isselected = !!res;
        });

        // 第二次遍历 将数据按树的结构进行组装
        const gassTree = ExtractGass.filter(el => el.parent_id === ServiceType.Gas);
        gassTree.forEach((node) => {
            node.children = []
            gass.forEach((gas) => {
                if (gas.parent_id === node.node_id) { node.children.push(gas); }
            });
        });

        return {
            formatStaffTree: staffs,
            formatVideoTree: videos,
            formatBroadCastTree: broadcasts,
            formatGasTree: gassTree,
            formatVentilation: ventination
        }
    }

    setFontCss(treeId, treeNode) {
        if (rootNodeList.includes(treeNode.name)) {
            return { color: 'black' }
        }
        // 灰色代表节点的位置已经被设置过了，绿色表示节点的位置还没有被设置过
        return treeNode.isselected ? {color: "green"} : {color: "gray"};
    }

    async PositionDbRefresh() {
        const { data: newpositions } = await this.api.getSmPositions(ServiceType.Mine_Id);
        const currentVideoPos = newpositions.filter((po) => {
            return po.layer === LayerType.SMVideo;
        });
        const currentStaffPos = newpositions.filter((po) => {
            return po.layer === LayerType.SMStaff;
        });
        const currentBroadCastPos = newpositions.filter((po) => {
            return po.layer === LayerType.SMBroadCast;
        });
        const currentGasPos = newpositions.filter((po) => {
            return po.layer === LayerType.SMGas;
        });
        const currentVentialPos = newpositions.filter((po) => {
            return po.layer === LayerType.SMVentilate;
        });

        // 根据 筛选后的数据，去更新indexDb
        await this.db.refresh(LayerType.SMStaff, currentStaffPos);
        await this.db.refresh(LayerType.SMVentilate, currentVentialPos);
        await this.db.refresh(LayerType.SMBroadCast, currentBroadCastPos);
        await this.db.refresh(LayerType.SMVideo, currentVideoPos);
        await this.db.refresh(LayerType.SMGas, currentGasPos);
    }

    // 树节点 单击人员分站节点触发函数
    async staffNodeClick(node_id) {
        console.log('触发了人员分站单击');
        const { data: position_staff } = await this.api.getSmPosition(
            ServiceType.Mine_Id, node_id, ServiceType.Staff
        );
        const {x, y} = position_staff;
        this.ztreeUtil.featureLocate([x, y]);
    }

    // 树节点 拖动人员分站节点触发函数
    async staffNodeDrag(node_id, iselected, treeNode) {
        const Coordinates = this.DragCoordinate;
        if (iselected) {
            // 双击的节点是已经设置过位置的
            await this.api.updatePosition(
                {
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Staff,
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    layer: LayerType.SMStaff
                }
            );
        } else {
            // 双击的节点 没有被设置过位置
            await this.api.addSmPosition(
                [{
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Staff,
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMStaff
                }]
            );
            await this.tree_init(false);
        }

        this.drawer.source(Type.Modify).clear();
        // 每次完成更新以后，都重新从m_positon表格中获取对应图层的数据
        await this.ztreeUtil.PositionDbRefresh();
        // indexDb数据库更新完成以后，手动更新一次 gis上的人员分站
        await this.drawer._safeMonitorStaff();
    }

    // 树节点 单击地下广播节点触发函数
    async broadcastNodeClick(node_id) {
        console.log('触发了地下广播单击')
        const { data: position_broadcast } = await this.api.getSmPosition(
            ServiceType.Mine_Id, node_id, ServiceType.BroadCast
        );
        const { x, y } = position_broadcast;
        this.ztreeUtil.featureLocate([x, y]);
    }

    // 树节点 拖动地下广播节点触发函数
    async broadcastNodeDrag(node_id, iselected, treeNode) {
        // 双击代表修改元素位置
        const Coordinates = this.DragCoordinate;
        if (iselected) {
            // 修改地下广播元素的位置信息
            await this.api.updatePosition(
                {
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.BroadCast,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMBroadCast
                }
            );
        } else {
            // 添加 地下广播的position信息
            await this.api.addSmPosition(
                [{
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.BroadCast,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMBroadCast
                }]
            );
            await this.tree_init(false);
        }

        this.drawer.source(Type.Modify).clear();

        // 每次完成更新以后，都重新从m_positon表格中获取对应图层的数据
        await this.ztreeUtil.PositionDbRefresh();

        // indexDb数据库更新完成以后，手动更新一次 gis上的人员分站
        await this.drawer._safeMonitorBroadcast();

    }

    // 树节点 单击监控系统摄像头 节点触发函数
    async videoNodeClick(node_id) {
        const { data: position_video } = await this.api.getSmPosition(
            ServiceType.Mine_Id, node_id, ServiceType.Video
        );
        const {x, y} = position_video;
        this.ztreeUtil.featureLocate([x, y]);
    }

    // 树节点 拖动 监控系统摄像头节点触发函数
    async videoNodeDrag(node_id, iselected, treeNode) {
        const Coordinates = this.DragCoordinate;
        if (iselected) {
            // 修改摄像头元素的位置信息
            await this.api.updatePosition(
                {
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Video,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMVideo
                }
            );
        } else {
            // 添加 地下广播的position信息
            await this.api.addSmPosition(
                [{
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Video,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMVideo
                }]
            );
            await this.tree_init(false);
        }
        this.drawer.source(Type.Modify).clear();
        // 每次完成更新以后，都重新从m_positon表格中获取对应图层的数据
        await this.ztreeUtil.PositionDbRefresh()
        // indexDb数据库更新完成以后，手动更新一次 gis上的人员分站
        await this.drawer._safeMonitorVideo();
    }

    // 通风设备 单击的触发函数
    async ventilateNodeClick(node_id) {
        const { data: position_ventilate } = await this.api.getSmPosition(
            ServiceType.Mine_Id, node_id, ServiceType.Gas
        );
        const {x, y} = position_ventilate;
        this.ztreeUtil.featureLocate([x, y]);
    }

    // 通风设备 拖动的触发函数
    async ventilateNodeDrag(node_id, isselected, treeNode) {
        const Coordinates = this.DragCoordinate;
        if (isselected) {
            // 修改地下广播元素的位置信息
            await this.api.updatePosition(
                {
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Gas,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMGas
                }
            );
        } else {
            // 添加 地下广播的position信息
            await this.api.addSmPosition(
                [{
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Gas,
                    // x: Coordinates[0],
                    // y: Coordinates[1],
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMGas
                }]
            )
            await this.tree_init(false);
        }

        // 每次完成更新以后，都重新从m_positon表格中获取对应图层的数据
        await this.ztreeUtil.PositionDbRefresh();
        // indexDb数据库更新完成以后，手动更新一次 gis上的人员分站
        await this.drawer._safeMonitorGas();
    }

    // 树节点 单击传感器节点触发函数
    async gasNodeClick(treeNode) {
        const { parent_id, node_id } = treeNode;
        const position = await this.api.getSmPosition(
            ServiceType.Mine_Id, node_id, ServiceType.Gas
        );
        const coordinate = [position.data.x, position.data.y];
        if (parent_id !== ServiceType.Gas) {
            // 代表点击的是三级节点(即具体传感器),元素定位
            this.ztreeUtil.featureLocate(coordinate);
            // 用线条体现 同一通道下的传感器关系
            this.ztreeUtil.highLightSensorRelation(treeNode);
        } else {
            // 如果点击的是二级节点 定位监控分站,加用线条连接关联的传感器,元素定位
            this.ztreeUtil.featureLocate(coordinate);
            // 用线条连接体现监控分站下 传感器的从属关系
            this.ztreeUtil.highLightStationRelation(treeNode);
        }
    }

    // 树节点 拖动传感器节点 触发函数
    async gasNodeDrag(node_id, isselected, treeNode) {
        const Coordinates = this.DragCoordinate
        if (isselected) {
            await this.api.updatePosition(
                {
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Gas,
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMGas
                }
            );
        } else {
            await this.api.addSmPosition(
                [{
                    mine_id: ServiceType.Mine_Id,
                    node_id: node_id,
                    service_type: ServiceType.Gas,
                    x: this.algo.denormalX(Coordinates[0]),
                    y: this.algo.denormalY(Coordinates[1]),
                    layer: LayerType.SMGas
                }]
            );
            await this.tree_init(false);
        }
        if(treeNode.parent_id === TreeNodeParent.Gas) {
            // 说明拖动的是监控分站,只要拖动了监控分站，就把下面的所属的传感器的位置信息全部删除
            const delInfos = treeNode.children.map((sensor) => {
                return {
                    mine_id:ServiceType.Mine_Id,
                    node_id:sensor.node_id,
                    service_type:ServiceType.Gas,
                    layerType:LayerType.SMGas
                };
            });
            // 批量删除 下属的传感器位置信息
            await this.api.delSmPositions(delInfos);
            // 然后  重新添加 传感器的位置信息
            const addInfos = delInfos.map((i) => {
                // 给一个随机坐标偏差值
                i.x = this.algo.denormalX(Coordinates[0]) + Math.random() * 100 - Math.random() * 100;
                i.y = this.algo.denormalY(Coordinates[1]) + Math.random() * 100 - Math.random() * 100;
                i.layer = i.layerType;
                delete i.layerType;
                return i;
            })
            await this.api.addSmPosition(addInfos);
            // 重置下目录树
            await this.tree_init(false);
        }
        // 每次完成更新以后，都重新从m_positon表格中获取对应图层的数据
        await this.ztreeUtil.PositionDbRefresh();
        // indexDb数据库更新完成以后，手动更新一次 gis上的人员分站
        await this.drawer._safeMonitorGas();
    }

    addEyesIcon(treeId, treeNode) {
        if (!treeNode.id) { return; }
        const aObj = $("#" + treeNode.tId + "_a");
        console.log('aObj--', aObj);
        const iconStr = `<span id='eyes_icon_${treeNode.id}' class="eye_open_style"></span>`;
        aObj.append(iconStr);
        const iconDom = $(`#eyes_icon_${treeNode.id}`);
        iconDom.bind('click', (e) => {
            treeNode.isShowLayer = !treeNode.isShowLayer;
            let operateLayerName = '';
            switch (treeNode.name) {
                // 点击的是安全监控目录根节点
                case rootNodeList[0]:
                    operateLayerName = LayerType.SMGas;
                    break;
                // 点击的是人员定位目录根节点
                case rootNodeList[1]:
                    operateLayerName = LayerType.SMStaff;
                    break;
                // 点击的是井下广播目录根节点
                case rootNodeList[2]:
                    operateLayerName = LayerType.SMBroadCast;
                    break;
                // 点击的是监控系统目录根节点
                case rootNodeList[3]:
                    operateLayerName = LayerType.SMVideo;
                    break;
                // 点击的是通风系统目录根节点
                case rootNodeList[4]:
                    operateLayerName = LayerType.SMVentilate;
                    break;
                default:
                    break;
            }
            if (treeNode.isShowLayer) {
                iconDom.attr('class', 'eye_open_style');
                // 根据树节点的不同 重新渲染不同的图层
                this.refreshLayer(operateLayerName);
            } else {
                iconDom.attr('class', 'eye_close_style');
                this.hiddenLayer(operateLayerName);
            }
        })
    }

    // 根据 图层类型，隐藏 对应图层
    hiddenLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                this.drawer.source(LayerType.SMStaff).clear()
                break
            case LayerType.SMBroadCast:
                this.drawer.source(LayerType.SMBroadCast).clear()
                break
            case LayerType.SMVideo:
                this.drawer.source(LayerType.SMVideo).clear()
                break
            case LayerType.SMGas:
                this.drawer.source(LayerType.SMGas).clear()
                break
            case LayerType.SMVentilate:
                this.drawer.source(LayerType.SMVentilate).clear()
                break
            default:
                break
        }
    }

    // 根据 图层类型，重新渲染 对应图层
    refreshLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                this.drawer._smstaff()
                break
            case LayerType.SMBroadCast:
                this.drawer._smbroadcast()
                break
            case LayerType.SMVideo:
                this.drawer._smvideo()
                break
            case LayerType.SMGas:
                this.drawer._smgas()
                break
            case LayerType.SMVentilate:
                this.drawer._smventilate()
                break
            default:
                break
        }

    }

    // 设置风向的函数
    ventilayeArrowSet() {
        // 首先 先把元素的选中效果移除
        this.selectInteraction.getFeatures().clear();
        const ventilate_feature = this.current_ventilate_featrue
        const coordinate = ventilate_feature.getGeometry().getCoordinates()
        this.drawer.map.getView().setCenter(coordinate)
        const modifySource = this.drawer.source(Type.Modify)
        // 创建画的 gis交互
        const drawInteraction = new Draw({
            source: modifySource,
            type: 'LineString',
            maxPoints: 2,
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)',
                }),
                stroke: new Stroke({
                    // color: 'rgba(255, 0, 0, 0.5)',
                    color: 'orange',
                    lineDash: [10, 10],
                    width: 2,
                }),
                image: new CircleStyle({
                    radius: 3,
                    stroke: new Stroke({
                        color: 'rgba(255, 0, 0, 0.7)',
                    }),
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 1)',
                    }),
                }),
            }),
        });
        drawInteraction.on('drawend', async (event) => {
            const feature = event.feature
            const coordinates = feature.getGeometry().getCoordinates()
            const startPointCoordinate = coordinates[0]
            const endPointCoordinate = coordinates[1]
            this.drawer.map.removeInteraction(drawInteraction)
            const timer = setTimeout(() => {
                modifySource.clear()
                clearTimeout(timer)
            }, 300)
            const slope = (endPointCoordinate[1] - startPointCoordinate[1]) / (endPointCoordinate[0] - startPointCoordinate[0])
            const rotation = -this.ztreeUtil.get_rel_rotation(endPointCoordinate, startPointCoordinate, slope)
            const res = await this.api.updateSmVentilateRotation(ServiceType.Mine_Id, 'person', ventilate_feature.get('node_id'), rotation)
        })
        this.drawer.map.addInteraction(drawInteraction)
        drawInteraction.appendCoordinates([coordinate])


    }

    async tree_init(isfirstInit) {
        // 初始化
        const {
            formatStaffTree,
            formatVideoTree,
            formatBroadCastTree,
            formatGasTree,
            formatVentilation
        } = await this.treeNodeDataInit();

        // zTree 的参数配置，深入使用请参考 API 文档（setting 配置详解）
        const setting = {
            view: {
                fontCss: this.setFontCss,
                addDiyDom: this.addEyesIcon.bind(this)
            },
            edit: {
                enable: true,
                showRemoveBtn: false,
                showRenameBtn: false
            },
            callback: {
                onClick: async (event, treeId, treeNode) => {
                    console.log('tree-node', treeNode);
                    if (rootNodeList.includes(treeNode.name)) {
                        // do nothing
                    } else if (treeNode.isselected) {
                        // 如果这个节点已经被设置过了，单击时，触发gis的定位功能
                        const {node_id, parent_id} = treeNode;
                        switch (parent_id) {
                            case TreeNodeParent.Staff:
                                await this.staffNodeClick(node_id);
                                break;
                            case TreeNodeParent.BroadCast:
                                await this.broadcastNodeClick(node_id);
                                break;
                            case TreeNodeParent.Video:
                                await this.videoNodeClick(node_id);
                                break;
                            case TreeNodeParent.Ventilate:
                                await this.ventilateNodeClick(node_id);
                                break;
                            // 当上面的条件都不满足的时候就证明，当前点击的节点是安全监控系统的节点（二级节点或者三级节点）
                            default:
                                await this.gasNodeClick(treeNode);
                                break;
                        }
                    } else if (!treeNode.isselected) {
                        // 节点没有被设置过的时候，单击 提醒用户 双击节点设置，位置
                        this.toast('此节点还没有被设置过，请拖动设置');
                    } else {
                        // do something
                    }
                },
                onRightClick: (event, treeId, treeNode) => {
                    // const {offsetLeft, offsetTop} = event.target
                    // const tmpDialog = document.createElement('div')
                    // tmpDialog.className = 'treeNodeRightClickStyle'
                    // const body = document.getElementsByTagName('body')[0]
                    // tmpDialog.style.left = `${offsetLeft + 90}px`
                    // tmpDialog.style.top = `${offsetTop + 80}px`
                    // tmpDialog.style.zIndex = 1000
                    // const deleteBtn = document.createElement('div')
                    // deleteBtn.className = 'RCdeleteInnerNodeStyle'
                    // const cancelBtn = document.createElement('div')
                    // cancelBtn.className = 'RCdeleteInnerNodeStyle'
                    // deleteBtn.innerText = '删除'
                    // cancelBtn.innerText = '取消'
                    // deleteBtn.addEventListener('click', async () => {
                    //     const treeNodesobj = treeNode
                    //     let serviceType = ''
                    //     let layerType = ''
                    //     switch (treeNodesobj.parent_id) {
                    //         case treeNodeParentDict.BroadCast:
                    //             serviceType = ServiceType.BroadCast
                    //             layerType = LayerType.SMBroadCast
                    //             break
                    //         case treeNodeParentDict.Staff:
                    //             serviceType = ServiceType.Staff
                    //             layerType = LayerType.SMStaff
                    //             break
                    //         case treeNodeParentDict.Video:
                    //             serviceType = ServiceType.Video
                    //             layerType = LayerType.SMVideo
                    //             break
                    //         case treeNodeParentDict.Ventilate:
                    //             serviceType = ServiceType.Gas
                    //             layerType = LayerType.SMGas
                    //             break
                    //         default:
                    //             serviceType = ServiceType.Gas
                    //             layerType = LayerType.SMGas
                    //     }
                    //     await this.api.delSmPosition({
                    //         mine_id: ServiceType.Mine_Id,
                    //         node_id: treeNode.node_id,
                    //         service_type: serviceType,
                    //         layerType: layerType
                    //     })
                    //     // 删除位置信息之后，重建 tree组件
                    //     this.tree_init(false)
                    //     // indexDb 以及 图层数据进行更新
                    //     await this.ztreeUtil.PositionDbRefresh()
                    //     // 这个函数也触发了底图元素的更新，需要重新为底图上色
                    //     await this.drawer.refresh()
                    //     this.drawer.refreshLayerCustomColor()
                    //     tmpDialog.remove()
                    // })
                    // cancelBtn.addEventListener('click', () => {
                    //     tmpDialog.remove()
                    // })
                    // tmpDialog.appendChild(deleteBtn)
                    // tmpDialog.appendChild(cancelBtn)
                    // body.appendChild(tmpDialog)
                    console.log('右键的节点是', treeNode)
                },
                beforeDrag: (treeId, treenodes) => {
                    if (rootNodeList.includes(treenodes[0].name)) {
                        // 如果 拖动的是最外层的目录，直接返回
                        return false;
                    }
                    this.PointerInteraction = new Pointer({
                        handleMoveEvent: (event) => this.DragCoordinate = event.coordinate
                    });
                    this.drawer.addInteraction(this.PointerInteraction);
                },
                beforeDrop: (treeId, treeNodes, targetNode, moveType) => {
                    // 只要触发了这个钩子函数 就表示拖拽 拖到了目录树里面
                    return false;
                },
                onDrop: (event, treeId, treeNodes) => {
                    // 查看拖动的位置 是不是 删除位置信息的位置
                    const className = event.target.className;
                    console.log('className', className);
                    if (className === 'truncateBox') {
                        const dialog = this.app.dialog.confirm('确定删除位置信息?', async () => {
                            // 确认
                            // mine_id,node_id,service_type,layer
                            const treeNodesobj = treeNodes[0]
                            let serviceType = ''
                            let layerType = ''
                            switch (treeNodesobj.parent_id) {
                                case TreeNodeParent.BroadCast:
                                    serviceType = ServiceType.BroadCast;
                                    layerType = LayerType.SMBroadCast;
                                    break;
                                case TreeNodeParent.Staff:
                                    serviceType = ServiceType.Staff;
                                    layerType = LayerType.SMStaff;
                                    break;
                                case TreeNodeParent.Video:
                                    serviceType = ServiceType.Video;
                                    layerType = LayerType.SMVideo;
                                    break;
                                case TreeNodeParent.Ventilate:
                                    serviceType = ServiceType.Gas;
                                    layerType = LayerType.SMGas;
                                    break;
                                default:
                                    serviceType = ServiceType.Gas;
                                    layerType = LayerType.SMGas;
                            }

                            await this.api.delSmPosition({
                                mine_id: ServiceType.Mine_Id,
                                node_id: treeNodes[0].node_id,
                                service_type: serviceType,
                                layerType: layerType
                            });

                            // 判断删除的是否是监控分站
                            if (treeNodes[0].parent_id === TreeNodeParent.Gas) {
                                // 是的话 就把他属下的所有传感器位置信息 也都删除
                                const deleteSensorInfos = treeNodes[0].children.map((child) => {
                                    return {
                                        mine_id: ServiceType.Mine_Id,
                                        node_id: child.node_id,
                                        service_type: serviceType,
                                        layerType: layerType
                                    }
                                });
                                await this.api.delSmPositions(deleteSensorInfos);
                            }
                            // 删除位置信息之后，重建 tree组件
                            await this.tree_init(false);
                            // indexDb 以及 图层数据进行更新
                            await this.ztreeUtil.PositionDbRefresh();
                            // 这个函数也触发了底图元素的更新，需要重新为底图上色
                            await this.drawer.refresh();
                            await this.drawer.refreshLayerCustomColor();
                        })
                    } else {
                        console.log('event.target', event.target);
                        console.log('drag 的最后位置', this.DragCoordinate);
                        this.drawer.removeInteraction(this.PointerInteraction);
                        const treeNode = treeNodes[0]
                        switch (treeNode.parent_id) {
                            case TreeNodeParent.Staff:
                                this.staffNodeDrag(treeNode.node_id, treeNode.isselected, treeNode);
                                break
                            case TreeNodeParent.BroadCast:
                                this.broadcastNodeDrag(treeNode.node_id, treeNode.isselected, treeNode);
                                break
                            case TreeNodeParent.Video:
                                this.videoNodeDrag(treeNode.node_id, treeNode.isselected, treeNode);
                                break
                            case TreeNodeParent.Ventilate:
                                this.ventilateNodeDrag(treeNode.node_id, treeNode.isselected, treeNode);
                                break
                            default:
                                // 如果以上的都不是 那就代表拖动的是传感器
                                this.gasNodeDrag(treeNode.node_id, treeNode.isselected, treeNode);
                                break
                        }
                    }

                }
            }
        };
        // zTree 的数据属性，深入使用请参考 API 文档（zTreeNode 节点数据详解）
        const zNodes = [
            {name: "安全监控", id: 'gas', open: true, isShowLayer: true, children: formatGasTree},
            {name: "人员定位", id: 'staff', open: true, isShowLayer: true, children: formatStaffTree},
            {name: "应急广播", id: 'broadcast', open: true, isShowLayer: true, children: formatBroadCastTree}
            // // 将视频监控 和 通风设备隐藏掉
            // { name: "视频监控", id: 'video', open: true, isShowLayer: true, children: formatVideoTree },
            // { name: "通风系统", open: true, isShowLayer: true, children: formatVentilation }
        ];
        // 判断是第一次初始化tree还是要对tree进行摧毁后重建
        if (isfirstInit) {
            $.fn.zTree.init($("#treeDemo"), setting, zNodes);
        } else {
            // 摧毁重构
            $.fn.zTree.destroy();
            $.fn.zTree.init($("#treeDemo"), setting, zNodes);
        }
    }

    // 创建 设置图层的dialog
    createrFeatureLayerChangeDialog() {
        return this.app.dialog.create({
            title: '设置巷道图层',
            cssClass: 'PAdialog',
            content: `
                <div class="PaDialogInnerBox">
                    <select id="layerChanger" style="width: 100%; height: 30px; margin: 5px auto;">
                    <select/>
                </div>
            `,
            buttons: [{
                text: '关闭'
            }, {
                text: '保存',
                onClick: async () => {
                    const changer = document.getElementById('layerChanger');
                    const selectLayerName = changer.value;
                    const { id: f_id, type } = this.currentSelectUnderLayFeature;
                    // 先对 model数据库中的元素信息进行修改
                    const res = await this.api.updateFeatureLayer(f_id, type, selectLayerName);
                    const { code, data } = res;
                    if (code === 0) {
                        const featureInfo = await this.db.operation(type, 'get', f_id);
                        featureInfo.layer = selectLayerName;
                        // 更新 indexdb中的 feature信息
                        await this.db.operation(type, 'put', featureInfo);
                        await this.db.refreshMeta(data.meta);
                        await this.drawer.refresh();
                        await this.drawer.refreshLayerCustomColor();
                    }
                }
            }],
            on: {
                opened: () => {
                    const changer = document.getElementById('layerChanger');
                    // 将弹窗内部的图层列表也渲染上
                    this.db.operation(Type.Layer, 'getAll').then((data) => {
                        let optionsTemplate = '';
                        data.forEach((layer) => {
                            optionsTemplate = optionsTemplate.concat(`
                                <option value="${layer.layer}">${layer.layer}</option>
                            `);
                        })
                        changer.innerHTML = optionsTemplate;
                    });
                }
            }
        });
    }
}
